/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "lwip/sockets.h"
#include "wifi_connect.h"

#include "wifiiot_errno.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_adc.h"
#include "wifiiot_uart.h"
#include "wifiiot_pwm.h"
#include "hi_io.h"
#include "hi_uart.h"
#include "hi_time.h"

#include <math.h>

#define UART_BUFF_SIZE 1000
#define BLOOD_SIZE 5 //30.125 30.1kPa 25min
#define CMD_LEN 1
#define READ_TIME 100

#define _PROT_ 8888
#define TCP_BACKLOG 10

#define BEGIN 'P'
#define CONNECT 'T'

#define BLUE_RX_1 1
#define BLUE_TX_0 0
#define NULL_STR "00000"

// 在sock_fd 进行监听，在 new_fd 接收新的链接
int sock_fd, new_fd;

unsigned char recvbuf[512];
//uint8_t *buf = 'a';

uint8_t uart_buff[5] = {0};
uint8_t *uart_buff_ptr = uart_buff;

static void MyUartInit(void)
{
	uint32_t ret;
	WifiIotUartAttribute uart_attr = {
		.baudRate = 115200,
		.dataBits = 8,
		.stopBits = 1,
		.parity = 0,
	};

	hi_io_set_func(BLUE_RX_1, HI_IO_FUNC_GPIO_1_UART1_RXD);
	hi_io_set_func(BLUE_TX_0, HI_IO_FUNC_GPIO_0_UART1_TXD);

	hi_uart_attribute my_uart1;
	my_uart1.baud_rate = 115200;
	my_uart1.data_bits = 8;
	my_uart1.parity = HI_UART_PARITY_NONE;
	my_uart1.stop_bits = 1;

	hi_uart_init(HI_UART_IDX_1, &my_uart1, NULL);
	return;

	// // Initialize uart driver
	// ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
	// if (ret != WIFI_IOT_SUCCESS)
	// {
	// 	printf("Failed to init uart! Err code = %d\n", ret);
	// 	return;
	// }
}

void Float2String(float src, char *desString, unsigned int mplace)
{
	float ftem = 0;
	unsigned int iplace = 1;
	unsigned int i = 0;
	if (src >= 0)
	{
		ftem = src;
	}
	else
	{
		ftem = -src;
	}

	if (ftem >= 10.0)
	{
		while (ftem >= 10.0)
		{
			iplace++;
			ftem /= 10;
		}
	}
	if (src < 0)
	{
		desString[0] = '-'; //
		i = 1;
		iplace++;
	}

	for (; i < iplace + mplace + 1; i++)
	{
		if (i == iplace)
		{
			if (mplace)
			{
				desString[i] = '.';
				continue;
			}
			else
				break;
		}
		else
		{
			desString[i] = (unsigned int)ftem;
			ftem -= desString[i];
			desString[i] += '0'; // 数值转换为字符 0x30 = '0'
			ftem *= 10;
		}
	}
}

static void TCPServerTask(void)
{
	MyUartInit();
	// 服务端地址信息
	struct sockaddr_in server_sock;

	// 客户端地址信息
	struct sockaddr_in client_sock;
	int sin_size;

	struct sockaddr_in *cli_addr;

	// 连接Wifi
	WifiConnect("r1", "88888889");

	// 创建socket
	if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket is error\r\n");
		exit(1);
	}

	bzero(&server_sock, sizeof(server_sock));
	server_sock.sin_family = AF_INET;
	server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
	server_sock.sin_port = htons(_PROT_);

	//调用bind函数绑定socket和地址
	if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
	{
		perror("bind is error\r\n");
		exit(1);
	}

	//调用listen函数监听(指定port监听)
	if (listen(sock_fd, TCP_BACKLOG) == -1)
	{
		perror("listen is error\r\n");
		exit(1);
	}

	printf("start accept\n");

	//调用accept函数从队列中
	while (1)
	{

		sin_size = sizeof(struct sockaddr_in);

		if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)
		{
			perror("accept");
			continue;
		}

		cli_addr = malloc(sizeof(struct sockaddr));

		printf("accept addr\r\n");

		if (cli_addr != NULL)
		{
			memcpy(cli_addr, &client_sock, sizeof(struct sockaddr));
		}

		//处理目标
		ssize_t ret;
		unsigned char msg_cmd = '0';
		// 读取止血数据

		while (1)
		{

			if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
			{
				printf("recv error \r\n");
			}
			printf("recv :%s\r\n", recvbuf);
			msg_cmd = recvbuf[0];

			printf("msg_cmd: %c\n", msg_cmd);
			switch (msg_cmd)
			{
			case 'p':
			{
				msg_cmd = BEGIN;
				printf("msg_cmd2: %c\n", msg_cmd);
				hi_uart_write(HI_UART_IDX_1, &msg_cmd, CMD_LEN);
				break;
			}
			case 't':
			{
				msg_cmd = CONNECT;
				printf("msg_cmd2: %c\n", msg_cmd);
				hi_uart_write(HI_UART_IDX_1, &msg_cmd, CMD_LEN);
				break;
			}
			default:
				break;
			}
			hi_uart_read(HI_UART_IDX_1, uart_buff, BLOOD_SIZE);
			//hi_uart_read_timeout(HI_UART_IDX_1,uart_buff,BLOOD_SIZE,READ_TIME);
			printf("uart_buff: %s\n", uart_buff);

			if ((ret = send(new_fd, uart_buff, BLOOD_SIZE, 0)) == -1)
			{
				perror("send : ");
			}
			uart_buff[0] = '0';
			uart_buff[1] = '0';
			uart_buff[2] = '0';
			uart_buff[3] = '0';
			uart_buff[4] = '0';
		}

		close(new_fd);
	}
}

static void TCPServerDemo(void)
{
	osThreadAttr_t attr;

	attr.name = "TCPServerTask";
	attr.attr_bits = 0U;
	attr.cb_mem = NULL;
	attr.cb_size = 0U;
	attr.stack_mem = NULL;
	attr.stack_size = 10240;
	attr.priority = osPriorityNormal;

	if (osThreadNew((osThreadFunc_t)TCPServerTask, NULL, &attr) == NULL)
	{
		printf("[TCPServerDemo] Falied to create TCPServerTask!\n");
	}
}

APP_FEATURE_INIT(TCPServerDemo);
